#include "MyString.h"
#include <stdexcept>

// Path: DrinkManageSystem\MyString.cpp

// Basic Functions

// Get the length of the string
int MyString::length()
{
	return mLength;
}

// Clear the string
void MyString::clear()
{
	if (mString == nullptr)
		return;
	delete[] mString;
	mString = nullptr;
	mLength = 0;
}

// Judge whether the string is empty
bool MyString::isEmpty()
{
	return mLength == 0;
}

// Constructors and destructor
MyString::MyString()
{
	mString = nullptr;
	mLength = 0;
}

MyString::MyString(const wchar_t* str)
{
	int length = 0;
	while (str[length] != '\0')
	{
		length++;
	}

	mString = new wchar_t[length + 1];
	for (int i = 0; i < length; i++)
	{
		mString[i] = str[i];
	}
	mString[length] = '\0';
	mLength = length;
}

MyString::MyString(const char* str)
{
	int length = 0;
	while (str[length] != '\0')
	{
		length++;
	}

	mString = new wchar_t[length + 1];
	for (int i = 0; i < length; i++)
	{
		mString[i] = static_cast<wchar_t>(str[i]);
	}
	mString[length] = '\0';
	mLength = length;
}

MyString::MyString(int num)
{
	int length = 0;
	int temp = num;
	while (temp != 0)
	{
		temp /= 10;
		length++;
	}

	mString = new wchar_t[length + 1];
	for (int i = length - 1; i >= 0; i--)
	{
		mString[i] = static_cast<wchar_t>(num % 10 + '0');
		num /= 10;
	}
	mString[length] = '\0';
	mLength = length;
}

MyString::MyString(double num, int accuracy)
{
	int length = 0;
	int temp = static_cast<int>(num);
	while (temp != 0)
	{
		temp /= 10;
		length++;
	}
	length += accuracy + 1;

	mString = new wchar_t[length + 1];
	for (int i = length - 1; i >= 0; i--)
	{
		if (i == length - accuracy - 1)
		{
			mString[i] = '.';
			continue;
		}
		mString[i] = static_cast<wchar_t>(static_cast<int>(num) % 10 + '0');
		num /= 10;
	}
	mString[length] = '\0';
	mLength = length;
}

MyString::MyString(const MyString& str)
{
	clear();
	mLength = str.mLength;
	mString = new wchar_t[mLength + 1];
	for (int i = 0; i < mLength; i++)
	{
		mString[i] = str.mString[i];
	}
	mString[mLength] = '\0';
}

MyString::~MyString()
{
	clear();
}

//Overload operators

//Overload operator =
MyString& MyString::operator=(const MyString& str)
{
	MyString temp;
	temp.mLength = mLength + str.mLength;
	temp.mString = new wchar_t[temp.mLength + 1];
	for (int i = 0; i < mLength; i++)
	{
		temp.mString[i] = mString[i];
	}
	for (int i = mLength; i < temp.mLength; i++)
	{
		temp.mString[i] = str.mString[i - mLength];
	}
	temp.mString[temp.mLength] = '\0';
	return temp;
}

//Overload operator +
MyString MyString::operator+(const MyString& str)
{
	MyString temp;
	temp.mLength = mLength + str.mLength;
	temp.mString = new wchar_t[temp.mLength + 1];
	for (int i = 0; i < mLength; i++)
	{
		temp.mString[i] = mString[i];
	}
	for (int i = mLength; i < temp.mLength; i++)
	{
		temp.mString[i] = str.mString[i - mLength];
	}
	temp.mString[temp.mLength] = '\0';
	return temp;
}

wchar_t& MyString::operator[](int index)
{
	if(index < 0 || index >= mLength)
		throw std::out_of_range("MyString index out of range");
	return mString[index];
}

//Overload operator +=
MyString& MyString::operator+=(const MyString& str)
{
	return (*this) = (*this) + str;
}

//Overload operator ==
bool MyString::operator==(const MyString& str)
{
	if (mLength != str.mLength)
		return false;
	for (int i = 0; i < mLength; i++)
	{
		if (mString[i] != str.mString[i])
			return false;
	}
	return true;
}